﻿using System;
using System.Runtime.Serialization;
using Game.Common;
using Game.ExtensibleObjects;
using Game.Objects;

namespace Game.Map.Extensions
{
    public static class GameObjectExtensionHelper
    {
        public static GameObjectExtension ObjectX(this IMapField field)
        {
            return field.Extensions.Find<GameObjectExtension>();
        }

    }

    [DataContract(Namespace = "game")]
    public class GameObjectExtension : IRuntimeExtension
    {
        public event EventHandler<FieldGameObjectEventArgs> ObjectAssigned;
        public event EventHandler<HasOwnerEventArgs> PlayerChanged;

        readonly IMapField _mapField;

        [DataMember] 
        public GameObject _GameObject;

        public GameObjectExtension(IRuntimeExtensibleObject source)
        {
            _mapField = source as IMapField;
        }

        [OnDeserialized]
        public void OnDeserialized2(StreamingContext c)
        {
            if (_GameObject != null && _GameObject.Building != null)
            {
                _GameObject.Building.PlayerChanged += (source, args) =>
                {
                    FirePlayerChanged();
                };
            }
        }
        
        public GameObject GameObject
        {
            get { return _GameObject; }
            set
            {
                GameObject save = _GameObject;
                _GameObject = value;
                FireObjectAssigned(save);
                if (_GameObject.Building != null)
                {
                    _GameObject.Building.PlayerChanged += (source, args) =>
                    {
                        FirePlayerChanged();
                    };
                }
            }
        }

        void FireObjectAssigned(GameObject save)
        {
            if (ObjectAssigned != null)
            {
                ObjectAssigned(this, new FieldGameObjectEventArgs(_mapField, save));
            }
        }
        
        void FirePlayerChanged()
        {
            if (PlayerChanged != null)
            {
                var args = new HasOwnerEventArgs(_GameObject.Building);
                PlayerChanged(this, args);
            }
        }
    }

    public class GameObjectExtensionFactory : IRuntimeExtensionFactory
    {
        public IRuntimeExtension CreateExtension(IRuntimeExtensibleObject source)
        {
            return new GameObjectExtension(source);
        }
    }

    public class FieldGameObjectEventArgs : EventArgs
    {
        readonly IMapField _mapField;
        readonly GameObject _oldItem;

        public FieldGameObjectEventArgs(IMapField mapField, GameObject oldItem)
        {
            _mapField = mapField;
            _oldItem = oldItem;
        }

        public IMapField MapField
        {
            get { return _mapField; }
        }

        public GameObject OldItem
        {
            get { return _oldItem; }
        }
    }

}
